package net.cyndeline.componentSystem.gameplay

import net.cyndeline.components.gameplay.TimeComponent
import net.cyndeline.entitySystem.AbstractEventHandlerSystem
import net.cyndeline.entitySystem.EntityRef
import net.cyndeline.entitySystem.Event
import net.cyndeline.entitySystem.defaultImpl.Aspect
import net.cyndeline.events.gameplay.TimeTickEvent
import com.escalatesoft.subcut.inject.BindingModule
import com.escalatesoft.subcut.inject.Injectable
import net.cyndeline.events.gameplay.TakeActionEvent
import net.cyndeline.events.gameplay.TakeAction

class TimeTickProcessingSystem(implicit val bindingModule: BindingModule) 
	extends AbstractEventHandlerSystem(
    new Aspect().getAll(classOf[TimeComponent]),
    classOf[TimeTickEvent])
	with Injectable {
  
  override def onEvent(event: Event, entity: EntityRef) {
    event match {
      case tick: TimeTickEvent => process(tick, entity)
      case _ => {}
    }
  }

  private def process(event: TimeTickEvent, entity: EntityRef) {
    val time: TimeComponent = entity.getComponent(classOf[TimeComponent]).get
    val timeLeft = time.timeLeft
    if (timeLeft <= 0) {
      throw new Error(entity + "has received a time tick event despite its " +
      		"time already being " + timeLeft + ". It should've been reset " +
      				"between the entitys last action and this tick.")
    }
    
    time.modify(event.finalAmount)
    
    if (time.timeLeft <= 0) {
      val timeForActionEvent = injectOptional [TakeActionEvent] getOrElse new TakeAction
      entity.send(timeForActionEvent)
    }
  }
}